/*
 * Copyright (C) 2025 Tsingteng MicroSystem
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file  osi_thread.c
 * @brief 线程相关接口实现
 * @date  2024-04-11
*/

#include "nfc_osi_api.h"
#include "nfc_log_api.h"
#include <string.h>

/**
 * @brief 创建线程
 *
 * 根据参数配置并创建线程
 * 线程创建完成后即会启动，线程返回后资源会自动回收
 *
 * @param thread_id 线程句柄指针
 * @param params 线程创建参数
 *
 * @return 成功时返回NFC_STATUS_OK
 */
tNFC_STATUS osi_thread_create(tTHREAD *thread_id, const tTHREAD_PARAMS *params)
{
    int status;
    pthread_attr_t attr;
    struct sched_param param;
    if ((NULL == thread_id) || (NULL == params) || (NULL == params->entry)) {
        NFCLOG_E("%s invalid params", __func__);
        return NFC_STATUS_INVALID_PARAM;
    }
    NFCLOG_D("%s enter.. name:%s priority:%d stack_size:%d", __func__, params->name,
        params->priority, params->stack_size);
    status = pthread_attr_init(&attr);
    if (status != 0) {
        NFCLOG_E("init pthread attr failed. ret:%d", status);
        return NFC_STATUS_FAILED;
    }

    if (!params->joinable) {
        status = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
        if (status != 0) {
            NFCLOG_E("set thread detach state failed. ret:%d", status);
            goto clean;
        }
    }
    if (!osi_memset(&param, sizeof(param), 0, sizeof(param))) {
        goto clean;
    }
    param.sched_priority = params->priority;
    status = pthread_attr_setschedparam(&attr, &param);
    if (status != 0) {
        NFCLOG_E("set thread priority failed. ret:%d", status);
        goto clean;
    }
    if (params->stack_size > 0) {
        status = pthread_attr_setstacksize(&attr, params->stack_size);
        if (status != 0) {
            NFCLOG_E("set thread stack size failed. ret:%d", status);
            goto clean;
        }
    }
    status = pthread_create(thread_id, &attr, params->entry, params->arg);
    if (status != 0) {
        NFCLOG_E("create thread failed. ret:%d", status);
        goto clean;
    }
    pthread_attr_destroy(&attr);
    return NFC_STATUS_OK;
clean:
    pthread_attr_destroy(&attr);
    return NFC_STATUS_FAILED;
}

/**
 * @brief 等待线程终止
 *
 * 等待指定的线程终止，并收回其资源。
 *
 * @param thread_id 要等待的线程句柄
 * @param ret_val 线程返回值，不需要时传NULL
 *
 * @return 成功时返回NFC_STATUS_OK
 */
tNFC_STATUS osi_thread_join(tTHREAD thread_id, void **ret_val)
{
    int status = pthread_join(thread_id, ret_val);
    if (status != 0) {
        NFCLOG_E("pthread_join failed: %s", strerror(status));
        return NFC_STATUS_FAILED;
    }
    return NFC_STATUS_OK;
}
